bitkeeper revision 1.1159.231.11 (41f97e1amKuDHSrW5ZWKsTy4ZIfNRA)
authoriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Thu, 27 Jan 2005 23:49:46 +0000 (23:49 +0000)
committeriap10@labyrinth.cl.cam.ac.uk <iap10@labyrinth.cl.cam.ac.uk>
Thu, 27 Jan 2005 23:49:46 +0000 (23:49 +0000)
Fix the direction flag for string I/O instructions.

Signed-off-by: Jun Nakajima <jun.nakajima@intel.com>
Signed-off-by: Chengyuan Li <chengyuan.li@intel.com>
Signed-off-by: ian.pratt@cl.cam.ac.uk
xen/arch/x86/vmx.c
xen/arch/x86/vmx_io.c
xen/include/public/io/ioreq.h

index 194311242b3fcac10484990066b0f737488c0d0c..acfc14eb4ce9db6a91b4c213a975c3e62789f781 100644 (file)
@@ -352,6 +352,10 @@ static void vmx_io_instruction(struct xen_regs *regs,
     p->size = (exit_qualification & 7) + 1;
 
     if (test_bit(4, &exit_qualification)) {
+        unsigned long eflags;
+
+        __vmread(GUEST_EFLAGS, &eflags);
+        p->df = (eflags & X86_EFLAGS_DF) ? 1 : 0;
         p->pdata_valid = 1;
         p->u.pdata = (void *) ((p->dir == IOREQ_WRITE) ?
             regs->esi
index 02333531a1c39f6bf4b41b49750216a1d9ca4284..85862f94ea94f426512dc4d447e6232f83e4c4a9 100644 (file)
@@ -39,8 +39,7 @@ void vmx_io_assist(struct exec_domain *ed)
     struct domain *d = ed->domain;
     execution_context_t *ec = get_execution_context();
     unsigned long old_eax;
-    unsigned long eflags;
-    int dir;
+    int sign;
 
     /* clear the pending event */
     ed->vcpu_info->evtchn_upcall_pending = 0;
@@ -68,24 +67,27 @@ void vmx_io_assist(struct exec_domain *ed)
         return;
     }
 
-    __vmread(GUEST_EFLAGS, &eflags);
-    dir = (eflags & X86_EFLAGS_DF);
+    sign = (p->df) ? -1 : 1;
+    if (p->port_mm) {
+        if (p->pdata_valid) {
+            ec->esi += sign * p->count * p->size;
+            ec->edi += sign * p->count * p->size;
+        } else {
+            if (p->dir == IOREQ_WRITE) {
+                return;
+            }
+        }
+    }
 
     if (p->dir == IOREQ_WRITE) {
         if (p->pdata_valid) {
-            if (!dir)
-                ec->esi += p->count * p->size;
-            else
-                ec->esi -= p->count * p->size;
+            ec->esi += sign * p->count * p->size;
             ec->ecx -= p->count;
         }
         return;
     } else {
         if (p->pdata_valid) {
-            if (!dir)
-                ec->edi += p->count * p->size;
-            else
-                ec->edi -= p->count * p->size;
+            ec->edi += sign * p->count * p->size;
             ec->ecx -= p->count;
             return;
         }
index c10dc46995571c6cc6c4cea963405c51ca57470e..ac47cd9ec5f60d518695979111f9101b39a1175a 100644 (file)
@@ -41,10 +41,11 @@ typedef struct {
         u64     data;           /*  data                        */
         void    *pdata;         /*  pointer to data             */
     } u;
-    u8      state:5;
+    u8      state:4;
     u8      pdata_valid:1;     /* if 1, use pdata above        */
     u8      dir:1;             /*  1=read, 0=write             */
     u8      port_mm:1;         /*  0=portio, 1=mmio            */
+    u8      df:1;
 } ioreq_t;
 
 #define MAX_VECTOR    256